package ecole.organisation;

import java.util.ArrayList ;

import reservation.Reservation;
import config.Config;
import ecole.utilisateur.Etudiant;
import ecole.utilisateur.Professeur;

/**
 * Classe ecole contenant toutes les composantes d'une école
 * 
 * @author Salah Bennour
 */
public class Ecole implements java.io.Serializable{
	
	private static final long serialVersionUID = 2L;
	protected ArrayList<Professeur> listeProfesseur ;
	protected ArrayList<Formation> listeFormation;
	
	protected String ville;
	protected int nbFormationMax = Config.MAX_FORMATION_ECOLE;
	protected final static String nom = Config.NOM_ECOLE;

	// ***************CONSTRUCTEURS*********************
	public Ecole(){
		listeProfesseur = new ArrayList<Professeur>();
		listeFormation = new ArrayList<Formation>();
	}

	public Ecole(String ville){
		this.ville = ville;
		listeProfesseur = new ArrayList<Professeur>();
		listeFormation = new ArrayList<Formation>();
	}

	// ***************METHODES*************************
	/**
	 * Methode permettant de devrifier si un professeur est dans l'ecole.
	 * @param prof est l'instance de la classe Professeur que l'on souhaite verifier son appartenance à l'ecole.
	 * @preturn boolean : true si le prof est dans l'ecole. False sinon.
	 */
	public Professeur rechercheProfesseurParNomPrenom(String nom, String prenom){
		for(int i=0; i< listeProfesseur.size() ;i++)
			if(listeProfesseur.get(i).getNom().equals(nom) && listeProfesseur.get(i).getPrenom().equals(prenom))
				return listeProfesseur.get(i);
		return null;
	}

	/**
	 * Methode permettant de devrifier si un professeur est dans l'ecole.
	 * @param prof est l'instance de la classe Professeur que l'on souhaite verifier son appartenance à l'ecole.
	 * @preturn boolean : true si le prof est dans l'ecole. False sinon.
	 */
	public boolean verifierProfesseurDansEcole(Professeur prof){
		return (listeProfesseur.contains(prof));
	}
	/**
	 * Methode permettant d'ajouter un etudiant à la formation.
	 * @param student est l'instance de la classe Etudiant que l'on souhaite ajouter a l'ecole.
	 * @param form est l'instance de la classe Formation que l'on souhaite ajouter à la formation.
	 */
	public void ajouterEtudiant(Etudiant student, Formation form){
		if ( !listeFormation.contains(form) ) //Si la formation (->form) n'est pas dans la liste de formation.
			System.out.println("Cette formation n'existe pas dans l'ecole!");
		else
		{
			for (int i=0 ; i<listeFormation.size(); i++)
			{
				if ( listeFormation.get(i).getIdFormation().equals(form.getIdFormation()) ) 
					listeFormation.get(i).ajouterEtudiant(student); //Ajoute etudiant à la liste d'etudiant de l'ecole
			}
		}
	}

	/**
	 * Methode permettant de retourner les enseignements ou le professeur passer en parametre est responsable.
	 * @param prof est l'instance de la classe Professeur que ou l'on souhaite consulter ces enseignement ou il est responsable.
	 * @return ArrayList<Enseignement> : est la liste des enseignements ou le professeur est responsable.
	 */
	public ArrayList<Enseignement> profEstRespEns(Professeur prof) {
		ArrayList<Enseignement> al = new ArrayList<Enseignement>();
		for (int i=0; i< this.getListeFormation().size() ; i++)
		{
			for ( int j=0; j<this.getListeFormation().get(i).getListeEnseignement().size() ; j++)
			{
				if (this.getListeFormation().get(i).getListeEnseignement().get(j).getRespEnseignement().equals(prof)) 
					al.add(this.getListeFormation().get(i).getListeEnseignement().get(j)); //retourne l'enseignement dont le prof est resp
			}
		}
		return al;
		
	}

	/**
	 * Methode permettant de retourner la formation ou le professeur passer en parametre est responsable.
	 * @param prof est l'instance de la classe Professeur que ou l'on souhaite consulter sa formation ou il est responsable.
	 * @return Formation : est la formation ou le professeur est responsable.
	 */
	public Formation profEstRespForm(Professeur prof) {
		if( prof.isResponsableFormation() )
		{
			for (int i=0; i< this.getListeFormation().size() ; i++)
			{
				if (this.getListeFormation().get(i).getRespoFormation().equals(prof) )
				{
					return this.getListeFormation().get(i);
				}
			}
		}
		return null;		
	}


	/**
	 * Methode permettant de retourner les formations qui suivent l'enseignement passé en parametre
	 * @param ens : est l'instance de la classe enseignement.
	 * @return ArrayList<Formation> : est la liste des formations qui suivent l'enseignement passer en parametres.
	 */
	public ArrayList<Formation> getFormationsEnseignement(Enseignement ens) {
		ArrayList<Formation> listForm = new ArrayList<Formation>();
		for (int i = 0 ; i< listeFormation.size() ; i++)
		{
			for (int j = 0 ; j<listeFormation.get(i).getListeEnseignement().size(); j++)
			{
				if( listeFormation.get(i).getListeEnseignement().get(j).equals(ens) )
				{
					listForm.add(listeFormation.get(i));
				}
			}
		}
		return listForm;
	}

	
	/**
	 * Methode permettant d'ajouter un enseignement à une formation donnée.
	 * @param nomEnseignement est le nom de la formation.
	 * @param formation est l'instance de la classe Formation.
	 * @param prof est l'instance de la classe Professeur.
	 * @param descriptif est la descritption d'un enseignement.
	 * @param coef est le coefficient de l'enseignement.
	 */
	public void ajouterEnseignement(Enseignement ens, Formation formation){//String nomEnseignement, Formation formation, Professeur prof, String descriptif, int coef){
		// Cherche formation dans la liste des formations de l'école (->listeFormation) => formTrouve
		Formation formTrouve = null;
		for (int i =0 ; i< listeFormation.size() ; i++)
		{
			if(listeFormation.get(i).equals(formation)) // si une formation de la liste de listeFormation est égale à formation
				formTrouve = listeFormation.get(i);
		}
		if(formTrouve == null) 
		{
			System.out.println(formation.getIdFormation()+" n'existe pas à l'école " +getEcoleNom()+ " !");
			return;
		}
		// Cherche le professeur(->prof) dans la liste des professeurs de l'école (->listeProfesseur) => profTrouve
		Professeur profTrouve = null; 
		for (int i =0 ; i< listeProfesseur.size() ; i++)
		{
			if(listeProfesseur.get(i).equals(ens.getRespEnseignement())) // si un professeur de la liste de listeGroupe est égale à prof
				profTrouve = listeProfesseur.get(i);

		}
		if(profTrouve == null) 
		{
			System.out.println(ens.getRespEnseignement().getNom()+" "+ens.getRespEnseignement().getPrenom() +" n'existe pas à l'école " +getEcoleNom()+ " !");
			return;
		}
		else{
		// Appelle la methode ajouterEnseignement de la classe Formation en faisant :
		formTrouve.ajouterEnseignement(ens);
		}
	}
	
	/**
	 * Methode permettant d'ajouter une formation a l'ecole.
	 * @param formation est l'instance de la classe Formation que l'on souhaite ajouter. 
	 */
	public void ajouterFormation(Formation formation){
		for (int i =0 ; i<listeFormation.size() ; i++)
		{
			//si on retrouve l'id(exSI3, SI4, MAM3..) de la formation passer en parametre dans la liste de formations
			if (listeFormation.get(i).getIdFormation().equals(formation.getIdFormation()))
			{
				System.out.println("Cette formation existe deja !");
				return;
			}
		}
		if(listeFormation.size() < nbFormationMax) //verifie si le nombre de formation est inférieur à 15
		{
			listeFormation.add(formation); // Ajoute la formation à la liste de formation de l'ec
			System.out.println("Formation ajoutée "+ formation.getIdFormation() +" à l'école "+ getEcoleNom());
		}
		else 
			System.out.println("Il y a deja trop de formation dans l'ecole !");
	}

	/**
	 * Methode permettant d'ajouter un professeur à la liste de l'ecole.
	 * @param prof est l'instance de la classe Professeur que l'on souhaite ajouter a l'ecole.
	 */
	public void ajouterProfesseur(Professeur prof){
		listeProfesseur.add(prof);
	}

	// ***************GETTER*************************
	/**
	 * Methode permettant d'obtenir tous les professeurs de l'ecole.
	 * @return ArrayList<Professeur> : tous les professeurs de l'ecole. 
	 */
	public ArrayList<Professeur> getListeProfesseur() {
		return listeProfesseur;
	}
	/**
	 * Methode permettant d'obtenir tous les professeurs de l'ecole.
	 * @return ArrayList<Formation> : toutes les formations de l'ecole. 
	 */
	public ArrayList<Formation> getListeFormation() {
		return listeFormation;
	}
	/**
	 *Methode permettant de retourner les informations d'une ecole telles que le nombre d'eleves, de professeurs...
	 * @return String : les informations de l'ecole.
	 */
	public String getInformationEcole(){
		String information = "";
		information = "Actuellement a l'ecole" +getNom()+ "'" +getVille()+
				"\n Nombre Professeur(s) : " + listeProfesseur.size() + 
				"\n Nombre Formation(s) : " +listeFormation.size();
		return information;
	}

	/**
	 * Methode permettant de retourner la ieme formation de la liste de formation de l'ecole.
	 * @param i est l'indice de la liste de formation de l'ecole.
	 * @return Formation : la ieme formation de la liste de formation de l'ecole.
	 */
	public Formation getFormation(int i){
		return listeFormation.get(i);
	}

	/**
	 * Methode permettant de retourner le ieme professeur de la liste de l'ecole.
	 * @param i est l'indice i de la liste des professeur de l'ecole.
	 * @return Professeur : le ieme professeur de la liste des professeur de l'ecole.
	 */
	public Professeur getProfesseur(int i){
		return listeProfesseur.get(i);
	}

	/**
	 * Methode permettant de retourner le nombre de professeur de l'ecole.
	 * @return int : le nombre de professeur de l'ecole.
	 */
	public int getNombreProfesseurEcole(){
		return listeProfesseur.size();
	}

	/**
	 * Methode permettant de retourner le nombre de formation de l'ecole.
	 * @return int : le nombre de formation de l'ecole.
	 */
	public int getNombreFormationEcole(){
		return listeFormation.size();
	}

	/**
	 * Methode permettant de retourner le nom de l'ecole.
	 * @return String : le nom de l'ecole.
	 */
	@SuppressWarnings("static-access")
	public String getNom(){
		return this.nom;
	}

	/**
	 * Methode permettant de retourner la ville de l'ecole.
	 * @return String : la ville de l'ecole.
	 */
	public String getVille(){
		return this.ville;
	}
	
	/**
	 * Methode permettant de retourner le nom complet de l'ecole (ex: Polytech'Nice-Sophia)
	 * @return String : la ville de l'ecole.
	 */
	public String getEcoleNom(){
		return  nom+""+getVille() ;
	}

	// ***************SETTER*************************
	/**
	 * Methode permettant de modifier la ville de l'ecole.
	 * @param ville est le nom de la nouvelle ville de l'ecole.
	 */
	public void setVille(String ville){
		this.ville = ville;
	}
	
	

	public void setListeProfesseur(ArrayList<Professeur> listeProfesseur) {
		this.listeProfesseur = listeProfesseur;
	}

	public void setListeFormation(ArrayList<Formation> listeFormation) {
		this.listeFormation = listeFormation;
	}

	// ***************TO STRING*************************
	public String toString(){
		return "Ecole :" +nom+""+getVille() ;
	}
}	